import { observer } from "./observer";
import { nextTick } from "./utils/nextTick";
import Watcher from "./compile/watcher";
export function initState(vm) {
  let ops = vm.$options;
  // console.log(ops);
  //判断
  if (ops.props) {
  }
  if (ops.data) {
    initData(vm);
  }
  if (ops.computed) {
  }
  if (ops.methods) {
  }
  if (ops.watch) {
    initWatch(vm);
  }
}
function initData(vm) {
  let data = vm.$options.data;
  data = vm._data = typeof data == "function" ? data.call(vm) : data;
  // 将data上的所有属性代理到  实例上
  for (let key in data) {
    // {name:'zs'}
    proxy(vm, "_data", key);
  }
  // console.log(data, "dat");
  observer(data);
}
function proxy(vm, source, key) {
  Object.defineProperty(vm, key, {
    get() {
      return vm[source][key];
    },
    set(newVal) {
      // console.log('色湖之了');
      vm[source][key] = newVal;
    },
  });
}
function initProps(vm) {}
function initWatch(vm) {
  let watch = vm.$options.watch;
  // 1.获取watch
  for (let key in watch) {
    //2.1获取  他的属性对应的值
    let handler = watch[key];
    if (Array.isArray(handler)) {
      handler.forEach((item) => {
        createWatcher(vm, key, item);
      });
    } else {
      //对象，字符串，函数
      createWatcher(vm, key, handler);
    }
  }
}

export function stateMixin(vm) {
  //列队
  vm.prototype.$nextTick = function (cb, vm) {
    nextTick(cb);
  };
  vm.prototype.$watch = function (expreOrfn, handler, options) {
    // console.log(expreOrfn, handler, options);
    let watcher = new Watcher(this,expreOrfn, handler, {...options,user:true})

    if (options.immediate) {
      handler.call(this); //如果有这个immediate立即执行
    }
  };
}
//vm.$watch(()=>{return 'a'})   返回的值就是 watcher 上的属性
//格式处理
function createWatcher(vm, expreOrfn, handler, options) {
  //3.1处理handler
  // console.log(handler);
  if (typeof handler === "object") {
    options = handler;
    handler = handler.handler;
  }
  if (typeof handler === "string") {
    handler = vm[handler];
  }

  //其他是 函数
  //  watch 最终处理 $watch 这个方法
  return vm.$watch(expreOrfn, handler, options);
}
